#include "ucolorpicker.h"

#include <QPainterPath>
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QtMath>
#include <QVBoxLayout>

class UColorPickerPrivate
{
public:
    UColorPickerPrivate(UColorPicker* q) : q_ptr(q) {}
    ~UColorPickerPrivate() {};

    QColor clickedPointColor(const QLineF &line, const QLineF &line1, bool intersects = false);

    QPointF colorToPoint(const QColor &color);

private:
    Q_DECLARE_PUBLIC(UColorPicker)
    Q_DISABLE_COPY(UColorPickerPrivate)
    UColorPicker* const q_ptr = nullptr;

    QColor realColor = QColor();
    QPointF currentPoint = QPointF();
    int radius = 260;
    bool isMove = false;
    bool isShow = true;
};

QColor UColorPickerPrivate::clickedPointColor(const QLineF &line, const QLineF &line1, bool intersects)
{
    qreal angle = line.angleTo(line1);
    qreal h = angle / 360.0;
    qreal s = intersects ? 1.0 : line1.length() / (radius / 2);
    QColor color;
    color.setHsvF(h, s, 1.0);
    return color;
}

QPointF UColorPickerPrivate::colorToPoint(const QColor &color)
{
    qreal length = color.hsvSaturationF() * (radius / 2);
    qreal angle = color.hsvHueF() * 360.0;
    qDebug() << length << angle << color.hsvHueF() << color.hsvSaturationF();
    qreal x = length * qCos(angle * M_PI / 180);
    qreal y = length * qSin(angle * M_PI / 180);
    return QPointF(x, -y);
}

UColorPicker::UColorPicker(QWidget* parent) : UWidget(parent)
    , d_ptr(new UColorPickerPrivate(this))
{
    setMinimumSize(300, 300);
}

UColorPicker::~UColorPicker()
{
}

void UColorPicker::setShowColorText(bool isShow)
{
    Q_D(UColorPicker);
    if (d->isShow != isShow)
    {
        d->isShow = isShow;
        update();
    }
}

void UColorPicker::setColor(const QColor &color)
{
    Q_D(UColorPicker);
    if (d->realColor != color)
    {
        d->realColor = color;
        d->currentPoint = rect().center() + d->colorToPoint(color);
        update();
        emit colorChanged(d->realColor);
    }
}

QColor UColorPicker::color() const
{
    Q_D(const UColorPicker);
    return d->realColor;
}

void UColorPicker::paintEvent(QPaintEvent* event)
{
    Q_D(UColorPicker);

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    QRect rect = QRect(this->rect().center() - QPoint(d->radius / 2, d->radius / 2), QSize(d->radius, d->radius));
    painter.drawPixmap(rect, QPixmap(":/images/colorpicker.png"));
    const QPalette &pal = palette();
    if (!d->currentPoint.isNull())
    {
        painter.setPen(Qt::black);
        painter.drawEllipse(d->currentPoint, 3, 3);
    }

    if (d->realColor.isValid() && d->isShow)
    {
        QFontMetrics fm(font());
        painter.setBrush(d->realColor);
        painter.resetTransform();
        painter.setPen(pal.color(QPalette::WindowText));
        painter.drawRect(width() - 40, height() - fm.height() * 2 - 26, 20, 20);
        painter.drawText(30, height() - fm.height() * 2, width() - 50, 30, Qt::AlignRight, d->realColor.name());
        painter.drawText(30, height() - fm.height(), width() - 50, 30, Qt::AlignRight, QString("R:%1,G:%2,B:%3").
                         arg(d->realColor.red()).arg(d->realColor.green()).arg(d->realColor.blue()));
    }
}

void UColorPicker::mousePressEvent(QMouseEvent* event)
{
    Q_D(UColorPicker);
    QPainterPath path;
    path.addEllipse(rect().center(), d->radius / 2, d->radius / 2);
    QPoint point = QPoint(rect().center().x() + d->radius / 2, rect().center().y());
    QLineF line = QLine(rect().center(), point);
    if (path.contains(event->pos()))
    {
        d->isMove = true;
        QLineF line1 = QLine(rect().center(), event->pos());
        d->realColor = d->clickedPointColor(line, line1);
        d->currentPoint = event->pos();
    }
    else
    {
        d->isMove = false;
    }
    update();
    emit colorChanged(d->realColor);
    UWidget::mousePressEvent(event);
}

void UColorPicker::mouseMoveEvent(QMouseEvent* event)
{
    Q_D(UColorPicker);
    if (!d->isMove)
    {
        QWidget::mouseMoveEvent(event);
        return;
    }
    QPoint point = QPoint(rect().center().x() + d->radius / 2, rect().center().y());
    QLineF line = QLine(rect().center(), point);
    QLineF line1 = QLine(rect().center(), event->pos());
    if (line1.length() >= (d->radius / 2))
    {
        d->realColor = d->clickedPointColor(line, line1, true);
        qreal angle = line.angleTo(line1);
        qreal x = (d->radius / 2) * qCos(angle * M_PI / 180);
        qreal y = (d->radius / 2) * qSin(angle * M_PI / 180);
        d->currentPoint = rect().center() + QPointF(x, -y);
    }
    else
    {
        d->realColor = d->clickedPointColor(line, line1);
        d->currentPoint = event->pos();
    }
    update();
    emit colorChanged(d->realColor);
    UWidget::mouseMoveEvent(event);
}

void UColorPicker::mouseReleaseEvent(QMouseEvent* event)
{
    Q_D(UColorPicker);
    d->isMove = false;
    UWidget::mouseReleaseEvent(event);
}
